package com.shawn.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.shawn.autoconfig.template.EMTemplate;
import com.shawn.commons.utils.RC;
import com.shawn.dubbo.api.*;
import com.shawn.model.dto.RecommendUserDto;
import com.shawn.model.entity.Question;
import com.shawn.model.entity.UserInfo;
import com.shawn.model.mongo.RecommendUser;
import com.shawn.model.mongo.UserLike;
import com.shawn.model.mongo.Visitors;
import com.shawn.model.vo.*;
import com.shawn.server.exception.BusinessException;
import com.shawn.server.exception.StrangerQuestionException;
import com.shawn.server.interceptor.ThreadContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.logging.log4j.util.Strings;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TouchLoveService {
    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @DubboReference
    protected UserLikeApi userLikeApi;

    @DubboReference
    private LocationApi locationApi;


    @DubboReference
    private VisitorsApi visitorsApi;

    @Resource
    private EMTemplate emTemplate;

    @Resource
    private MqMessageService mqMessageService;

    public TodayBest getTodayLove(Long userId) {
        RecommendUser todayLove = recommendUserApi.getTodayLove(userId);
        if(todayLove==null){
            //新用户,创建一个推荐用户测试
            todayLove = new RecommendUser();
            todayLove.setToUserId(userId);
            todayLove.setUserId(1L);
            todayLove.setScore(99D);
            todayLove.setDate(new Date().toString());
        }
        UserInfo userInfo = userInfoApi.findDetailById(todayLove.getUserId());
        //转化对象
        return TodayBest.init(userInfo, todayLove);
    }

    public PageResult<TodayBest> getRecommendList(RecommendUserDto recommendUserDto) {
        //获取当前用户id
        Long userId = ThreadContext.getUserId();

        //调用mongodb数据库路查询所有 上次登录时间满足 缘分值为80-100之间  推荐用户
        List<RecommendUser> recommendUsers = recommendUserApi.findByCondition(userId);
        if(recommendUsers.size()==0){
            return new PageResult<>();
        }
        Map<Long, RecommendUser> recommendUserMap = CollUtil.fieldValueMap(recommendUsers, "userId");
        //批量获取所有id
        List<Long> userIds = recommendUsers.stream().map(RecommendUser::getUserId).collect(Collectors.toList());

        //构建用户查询条件
        UserInfo userInfo = new UserInfo();
        //指定性别
        userInfo.setGender(recommendUserDto.getGender());
        //todo 指定登录时间
        //指定年龄
        userInfo.setAge(recommendUserDto.getAge());
        //指定居住地
        userInfo.setCity(recommendUserDto.getCity());
        //指定学历 向上兼容
        userInfo.setEducation(recommendUserDto.getEducation());
        //根据返回所有的用户id 分页查询userInfo
        PageResult<UserInfo> pageResult = userInfoApi.findByIds(userIds,userInfo,recommendUserDto.getPage(),recommendUserDto.getPagesize());
        //将所有的UserInfo对象转化为TodayBest vo对象
        List<UserInfo> userInfos = pageResult.getItems();

        if (userInfos==null){
            return null;
        }
        ArrayList<TodayBest> list = new ArrayList<>();
        for (UserInfo info : userInfos) {
            TodayBest todayBest = TodayBest.init(info, recommendUserMap.get(info.getId()));
            list.add(todayBest);
        }
        return new PageResult<>(pageResult.getPage(), pageResult.getPagesize(),pageResult.getCounts(),list);
    }
    @Cacheable(value = "userInformation",key = "#id")
    public TodayBest findTodayBestById(Long id) {
        UserInfo userInfo = userInfoApi.findDetailById(id);
        Long userId = ThreadContext.getUserId();
        RecommendUser user =  recommendUserApi.findByBothId(userId,id);
        if (user==null){
            //如果没有先构造缘分值95
            user= new RecommendUser();
            user.setScore(95D);
        }
        if (!Objects.equals(id, userId)) {
            //发送mq异步消息
            //记录访客信息
            //保存数据
            mqMessageService.sendVisitorDataMessage(id, userId,"首页");

        }
        //查询推荐系统两人匹配评分

        return TodayBest.init(userInfo,user);
    }



    /**
    发送好友请求
    "userId": 106,
	"huanXinId": "hx106",
	"nickname": "黑马小妹",
	"strangerQuestion": "你喜欢去看蔚蓝的大海还是去爬巍峨的高山？",
	"reply": "我喜欢秋天的落叶，夏天的泉水，冬天的雪地，只要有你一切皆可~"*/
    public void answerStrangerQuestion(Long toUserId, String questionReply) {
        Long userId = ThreadContext.getUserId();
        UserInfo userInfo = userInfoApi.findDetailById(userId);
        Map map = new HashMap();
        map.put("userId",userId);
        map.put("huanXinId", RC.HX_USER_PREFIX+userId);
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",getStrangerQuestion(toUserId));
        map.put("reply",questionReply);
        //转化为json
        String message = JSON.toJSONString(map);
        String toHXUserId = RC.HX_USER_PREFIX+toUserId;
        Boolean result = emTemplate.sendMessage(toHXUserId, message);
        if (!result){
            //未知错误!
            throw new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 得到陌生人问题
     *
     * @param userId 用户id
     * @return {@link String}
     */
    public String getStrangerQuestion(Long userId) {
        Question question = questionApi.getQuestionByUserId(userId);
        if (question==null){
            String defaultQuestion = "你喜欢编程吗?";
            Question qu = new Question();
            qu.setUserId(userId);
            qu.setTxt(defaultQuestion);
            //设置陌生人问题
            questionApi.insertDefaultQuestion(qu);
            throw new StrangerQuestionException(ErrorResult.builder().errMessage(defaultQuestion).build());
        }
        return question.getTxt();
    }

    //指定默认数据
    @Value("${touch.default.recommend.users}")
    private String recommendUser;

    public List<TodayBest> recommendCards(Long userId) {
        //1、调用推荐API查询数据列表（排除喜欢/不喜欢的用户，数量限制）
        List<RecommendUser> recommendUsers = recommendUserApi.getRecommendCards(userId,10);
        if(CollUtil.isEmpty(recommendUsers)) {
           //构造推荐用户
            String[] userIds = recommendUser.split(",");
            for (String id : userIds) {
                recommendUsers= new ArrayList<>();
                RecommendUser user = new RecommendUser();
                user.setUserId(Long.valueOf(id));
                user.setScore(RandomUtil.randomDouble(80,99));
                recommendUsers.add(user);
            }
        }
        //获取到所有id
        List<Long> ids = recommendUsers.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        Map<Long, RecommendUser> recommendUserMap = CollUtil.fieldValueMap(recommendUsers, "userId");

        //获取所有用户信息
        List<UserInfo> userInfos = userInfoApi.findByIds(ids);
        List<TodayBest> todayBestList = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            TodayBest todayBest = TodayBest.init(userInfo, recommendUserMap.get(userInfo.getId()));
            todayBestList.add(todayBest);
        }
        return todayBestList;
    }

    public void whetherLoveUser(Long userId, Long loveId,Boolean isLike) {
        UserLike userLike = new UserLike();
        userLike.setUserId(userId);
        userLike.setLikeUserId(loveId);
        userLike.setIsLike(isLike);
        userLike.setCreated(System.currentTimeMillis());
        userLike.setUpdated(System.currentTimeMillis());
        if (isLike) {
            //判断对方是否也喜欢自己
            boolean loveRes = userLikeApi.checkLove(userId,loveId);
            if (loveRes){
                //将两人绑定为好友
                boolean fr = emTemplate.addFriend(RC.HX_USER_PREFIX + userId, RC.HX_USER_PREFIX + loveId);
                if (!fr)
                    throw new BusinessException(ErrorResult.faceError());
                else
                    log.info("成功添加对方好友!");
            }
            userLikeApi.save(userLike);
        }
    }

    /**
     * 搜索附近人
     *
     * @param userId   用户id
     * @param gender   性别
     * @param distance 距离
     * @return {@link List}<{@link NearlyUserVo}>
     */
    public List<NearlyUserVo> searchNearlyPeople(Long userId, String gender, String distance) {
        //查询指定的附近用户
        List<Long> ids = locationApi.searchNearlyPeople(userId, gender, distance);
        if (ids==null){
            return new ArrayList<>();
        }
        List<UserInfo> userInfos = userInfoApi.findByIds(ids);
        return userInfos.stream().map(NearlyUserVo::init).collect(Collectors.toList());
    }
}
